#pragma once
#include"noncopyable.h"
#include"InetAddress.h"
#include"Callbacks.h"
#include"Timestamp.h"
#include"Buffer.h"
#include<memory>
#include<atomic>
#include<string>
class Channel;
class Eventloop;
class Socket;
/* 
TcpServer通过Acceptor有一个新用户链接，通过accept函数拿到connfd，TcpConnection设置回调给Channel通过它再注册
到poller上，接着有事件之后就会调用回调函数
*/
class TcpConnection:noncopyable,public std::enable_shared_from_this<TcpConnection>
{
    public:
        TcpConnection(Eventloop *loop,
                        const std::string &nameArg,
                        int sockfd,
                        const InetAddress &localAddr,
                        const InetAddress &peerAddr);
        ~TcpConnection();
        Eventloop* getloop() const {return loop_;}
        const std::string& name() const {return name_;}
        const InetAddress& localAddress() const {return localAddr_;}
        const InetAddress& peerAddress() const {return peerAddr_;}
        bool connected() const {return state_==kConnected;}
        void send(const std::string &buf);
        void shutdown();//关闭当前连接
        void setConnectionCallback(const ConnectionCallback& cb){connectionCallback_=cb;}
        void setMessageCallback(const MessageCallback &cb){messageCallback_=cb;}
        void setWriteCompleteCallback(const WriteCompleteCallback& cb){writeCompleteCallback_=cb;}
        void setHighWaterMarkCallback(const HighWaterMarkCallback& cb,size_t highWaterMark)
        {highWaterMarkCallback_=cb;highWaterMark_=highWaterMark;}
        void setCloseback(const CloseCallback& cb){closeCallback_=cb;}

        //建立连接和销毁连接
        void connectEstablished();
        void connectDestroyed();
        


    private:
    enum StateE{kDisconnected ,kConnecting,kConnected,kDisConnecting};//连接状态
    void setState(StateE state){state_=state;}
    void handleRead(Timestamp receiveTime);
    void handleWrite();
    void handleClose();
    void handleError();
    
    

    void sendInLoop(const void* message,size_t len);//确保所有操作在同一个线程中串行执行
    void shutdownInLoop();
    Eventloop *loop_;//这里绝对不是baseloop，因为TcpConnection都是在subloop中管理的
    const std::string name_;
    std::atomic_int state_;
    bool reading_;

    std::unique_ptr<Socket> socket_;
    std::unique_ptr<Channel> channel_;

    const InetAddress localAddr_;
    const InetAddress peerAddr_;

    ConnectionCallback connectionCallback_;//有新连接时候的回调
    MessageCallback messageCallback_;//有读写消息时候的回调
    WriteCompleteCallback writeCompleteCallback_;//消息发送完之后的回调
    HighWaterMarkCallback highWaterMarkCallback_;
    CloseCallback closeCallback_;
    
    size_t highWaterMark_;//发送缓冲区的高水位线，如64MB

    Buffer inputBuffer_;//接受数据的缓冲区
    Buffer outputBuffer_;//发送数据的缓冲区
};